Vamos importar o conjunto de dados scorestotal.xlsx e relembrar qual é a média da coluna presente
dados.scores = read_excel("scorestotal.xlsx")
mean(dados.scores$presente)## [1] 52.62
Vamos dar uma olhada na distribuição dos dados de média 52.62
Cada ponto x tem uma variação v da média µ, que pode ser calculado como x-µ
O valor de variação da nota 0 com relação à média é 0-52.62 = -52.62
O valor de variação da nota 90 com relação à média é 90-52.65 = 37.35
A soma das variações é sempre 0, e portanto não é muito útil para descrever a dispersão dos dados
Podemos criar um vetor com o valor da variação de cada ponto com relação à média no R. Vamos chamar esse vetor de distancia.da.media
distancia.da.media = c(dados.scores$presente - mean(dados.scores$presente))
distancia.da.media## [1] -30.62 2.38 1.38 -1.62 37.38 -14.62 14.38 -6.62 2.38 -15.62
## [11] 12.38 -0.62 5.38 -3.62 0.38 4.38 5.38 -0.62 -1.62 7.38
## [21] -3.62 25.38 6.38 5.38 3.38 9.38 7.38 3.38 -2.62 18.38
## [31] 3.38 8.38 -5.62 -6.62 0.38 -37.62 -9.62 -20.62 -2.62 -26.62
## [41] 6.38 -2.62 -2.62 -20.62 2.38 -4.62 -15.62 22.38 16.38 -22.62
## [51] -18.62 9.38 9.38 6.38 2.38 1.38 1.38 4.38 10.38 4.38
## [61] -43.62 -7.62 -8.62 4.38 -11.62 7.38 6.38 5.38 11.38 3.38
## [71] 3.38 -1.62 2.38 4.38 11.38 -2.62 10.38 -5.62 -3.62 2.38
## [81] -4.62 8.38 -0.62 -7.62 -19.62 1.38 15.38 -7.62 3.38 5.38
## [91] 9.38 7.38 27.38 3.38 -52.62 6.38 7.38 -0.62 -0.62 8.38
Aqui nós vemos que a soma desses valores é ZERO
soma.d.m = sum(distancia.da.media)
soma.d.m## [1] 2.557954e-13
Uma maneira de resolver o problema da soma das distâncias da média é considerar o valor absoluto da distância dos pontos (ou seja, tirar o sinal negativo)
distancia.absoluta.da.media = abs(distancia.da.media)
distancia.absoluta.da.media## [1] 30.62 2.38 1.38 1.62 37.38 14.62 14.38 6.62 2.38 15.62 12.38
## [12] 0.62 5.38 3.62 0.38 4.38 5.38 0.62 1.62 7.38 3.62 25.38
## [23] 6.38 5.38 3.38 9.38 7.38 3.38 2.62 18.38 3.38 8.38 5.62
## [34] 6.62 0.38 37.62 9.62 20.62 2.62 26.62 6.38 2.62 2.62 20.62
## [45] 2.38 4.62 15.62 22.38 16.38 22.62 18.62 9.38 9.38 6.38 2.38
## [56] 1.38 1.38 4.38 10.38 4.38 43.62 7.62 8.62 4.38 11.62 7.38
## [67] 6.38 5.38 11.38 3.38 3.38 1.62 2.38 4.38 11.38 2.62 10.38
## [78] 5.62 3.62 2.38 4.62 8.38 0.62 7.62 19.62 1.38 15.38 7.62
## [89] 3.38 5.38 9.38 7.38 27.38 3.38 52.62 6.38 7.38 0.62 0.62
## [100] 8.38
Somando a distância absoluta de todos os pontos da média e dividindo pelo número de observações, temos uma espécie de “média” dos desvios. É o que chamamos desvio absoluto
distancia.absoluta.da.media = abs(distancia.da.media)
sum(distancia.absoluta.da.media)/100## [1] 9.1484
Outra maneira de resolver o problema da soma zero das distâncias do ponto com relação à média é elevar esse valor ao quadrado.
distancia.da.media.ao.quadrado = (distancia.da.media)^2
distancia.da.media.ao.quadrado## [1] 937.5844 5.6644 1.9044 2.6244 1397.2644 213.7444 206.7844
## [8] 43.8244 5.6644 243.9844 153.2644 0.3844 28.9444 13.1044
## [15] 0.1444 19.1844 28.9444 0.3844 2.6244 54.4644 13.1044
## [22] 644.1444 40.7044 28.9444 11.4244 87.9844 54.4644 11.4244
## [29] 6.8644 337.8244 11.4244 70.2244 31.5844 43.8244 0.1444
## [36] 1415.2644 92.5444 425.1844 6.8644 708.6244 40.7044 6.8644
## [43] 6.8644 425.1844 5.6644 21.3444 243.9844 500.8644 268.3044
## [50] 511.6644 346.7044 87.9844 87.9844 40.7044 5.6644 1.9044
## [57] 1.9044 19.1844 107.7444 19.1844 1902.7044 58.0644 74.3044
## [64] 19.1844 135.0244 54.4644 40.7044 28.9444 129.5044 11.4244
## [71] 11.4244 2.6244 5.6644 19.1844 129.5044 6.8644 107.7444
## [78] 31.5844 13.1044 5.6644 21.3444 70.2244 0.3844 58.0644
## [85] 384.9444 1.9044 236.5444 58.0644 11.4244 28.9444 87.9844
## [92] 54.4644 749.6644 11.4244 2768.8644 40.7044 54.4644 0.3844
## [99] 0.3844 70.2244
O resultado da soma das distâncias da média ao quadrado dividido pelo número de observações é o que chamamos variância
sum(distancia.da.media.ao.quadrado)/100## [1] 176.5156
Uma das medidas mais usadas para descrever a dispersão dos dados é o desvio-padrão
O desvio padrão é a raiz-quadrada da variância
variancia = sum(distancia.da.media.ao.quadrado)/100
sqrt(variancia)## [1] 13.28592
Quando reportamos nossos dados, é muito comum reportarmos o desvio-padrão para que o leitor saiba qual foi o “espalhamento” dos valores da amostra.
A boa notícia é que o R tem um função que faz isso, e portanto você não precisa lembrar de todas as contas que acabamos de fazer =D
sd(dados.scores$presente)## [1] 13.35285
Geralmente, a maioria dos seus dados (cerca de 68%) estará em um intervalo entre média-D.P. e média+D.P.
Por esse motivo, o desvio-padrão é importante porque ele informa quão espalhados estão seus dados.
dp = sd(dados.scores$presente)
media = mean(dados.scores$presente)
media + dp## [1] 65.97285
media - dp## [1] 39.26715
Podemos ver os valores do slide anterior no histograma abaixo
Os quartis dividem o conjunto de dados em pedaços, mais ou menos como a mediana (que, nesse caso, é o Q2). Vejamos:
(fonte: https://mathbitsnotebook.com/Algebra1/StatisticsData/STboxplot.html
Podemos pensar que os quartis dividem nossos dados em partes iguais.
A amplitude interquartil (ou interquartile range, ou IQR) é o valor de Q3-Q1. Quanto maior esse valor, maior a dispersão dos dados.
A amplitude interquartil também é dada pelo R através da função abaixo.
IQR(dados.scores$presente)## [1] 10.5
Vamos supor que o professor que coletou os dados do conjunto scorestotal tenha motivos para querer eliminar todas as notas iguais ou abaixo de 30. Depois de plotar o gráfico, o professor viu que havia apenas 5 observações abaixo desse valor. Ao conferir os alunos que tiraram essas notas, ele percebeu que um dos alunos (nota 0) faltou no dia da prova, e que os outros dois que tiraram notas muito baixas, abaixo de 30, nunca compareceram às aulas (acontece…).
O professor suspeita que manter esses dados não dá uma boa amostra de como os alunos que compareceram às aulas e à prova se saíram no teste, e por isso resolve fazer uma nova análise excluindo esses valores extremos.
Vamos criar um subconjunto dos dados para analisar, excluindo as medidas menores que 20.
Nunca, nunca, em hipótese alguma, mexa no seu conjunto de dados ou crie um conjunto de dados novo, ou vc vai ter uma pasta parecida com a pasta do meu mestrado, que eu nunca mais consegui entender.O R conta com o dplyr um ótimo pacote para manipular seu conjunto de dados. Uma vez que você escreva seu script com ele, não precisará criar arquivos novos em sua pasta. Ele faz parte de um pacote maior, chamado tidyverse, que precisa ser baixado e carregado.
install.packages("tidyverse")
library(tidyverse)O dplyr funciona com um operador que chamamos ‘pipe’, representado como %>%. Ele permite que você use o output de uma linha L como input da linha seguinte L+1. Vamos ver um exemplo:
linha 1 - cria um conjunto novos.dados a partir de dados.scores
linha 2 - seleciona apenas a coluna “presente” do conjunto criado na linha 1
linha 3 - filtra apenas aqueles valores iguais ou maiores que 30 para a coluna presente no conjunto criado na l2
novos.dados = dados.scores%>% #linha 1
select(presente)%>% #linha 2
filter(presente >= 30) #linha 3Para conferir, organize em ordem crescente os valores da coluna “presente” em dados.scores (o conjunto total) e novos.dados.
sort(dados.scores$presente)## [1] 0 9 15 22 26 30 32 32 33 34 37 37 38 41 43 44 45 45 45 46 46 47 47
## [24] 48 48 49 49 49 50 50 50 50 50 51 51 51 52 52 52 52 52 53 53 54 54 54
## [47] 54 55 55 55 55 55 55 56 56 56 56 56 56 56 57 57 57 57 57 58 58 58 58
## [70] 58 59 59 59 59 59 60 60 60 60 60 61 61 61 62 62 62 62 63 63 64 64 65
## [93] 67 68 69 71 75 78 80 90
sort(novos.dados$presente)## [1] 30 32 32 33 34 37 37 38 41 43 44 45 45 45 46 46 47 47 48 48 49 49 49
## [24] 50 50 50 50 50 51 51 51 52 52 52 52 52 53 53 54 54 54 54 55 55 55 55
## [47] 55 55 56 56 56 56 56 56 56 57 57 57 57 57 58 58 58 58 58 59 59 59 59
## [70] 59 60 60 60 60 60 61 61 61 62 62 62 62 63 63 64 64 65 67 68 69 71 75
## [93] 78 80 90
Tire a média, mediana, desvio padrão, IQR e plote um novo histograma desse conjunto de dados
mean (novos.dados$presente)## [1] 54.63158
median(novos.dados$presente)## [1] 55
sd (novos.dados$presente)## [1] 10.07108
summary(novos.dados$presente)## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 30.00 50.00 55.00 54.63 60.00 90.00
sd (novos.dados$presente)## [1] 10.07108
Vamos comparar os valores de tendência central dos dados brutos e dos dados que filtramos usando dplyr. Você percebe alguma tendência?
summary(novos.dados$presente)## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 30.00 50.00 55.00 54.63 60.00 90.00
summary(dados.scores$presente)## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.00 48.75 55.00 52.62 59.25 90.00
Agora vamos ver o desvio-padrão…
sd (novos.dados$presente)## [1] 10.07108
sd (dados.scores$presente)## [1] 13.35285
…e o IQR. Você percebe alguma diferença? Em que sentido? Como isso se relaciona com o filtro que fizemos?
IQR (novos.dados$presente)## [1] 10
IQR (dados.scores$presente)## [1] 10.5
ggplot(novos.dados, aes(x=presente, y=))+
geom_histogram(breaks=seq(0,100, by = 1))+
scale_x_continuous(breaks=pretty_breaks(n=10))+
labs(x="Nota na prova (presente, maior ou igual a 30)", y="Número de alunos")Lembra dos quartis?
Outra maneira de visualizar dados é com um gráfico chamado boxplot, que usa justamente informações fornecidas pelos quartis e as organiza graficamente.
Você pode ver que a “caixa” do primeiro quartil até a mediana é mais comprida, isso significa que os dados estão mais espalhados à esquerda da mediana. Vejamos alguns exemplos.
Sven está se preparando para uma maratona de 15 milhas. O conjunto abaixo tem o número de milhas que ele correu em cada um dos seus 23 treinos e as medidas descritivas das observações.
milespp = c(2, 2, 3, 4, 5, 5, 6, 6, 7, 5, 8, 9, 2, 10, 11, 4, 12, 2, 13, 4, 15, 5, 11)
sort(milespp)## [1] 2 2 2 2 3 4 4 4 5 5 5 5 6 6 7 8 9 10 11 11 12 13 15
summary(milespp)## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2.000 4.000 5.000 6.565 9.500 15.000
Fonte: https://mathbitsnotebook.com/Algebra1/StatisticsData/STcompare.html
Fonte: https://mathbitsnotebook.com/Algebra1/StatisticsData/STcompare.html
Geralmente os boxplots são desenhados na vertical, mas o raciocínio é o mesmo.
Fonte: http://www.helicaltech.com/tag/business-intelligence/page/5/
Vamos comparar os dados da coluna presente em dados.scores com boxplot e histograma
A linha mais grossa é a mediana (55), a linha inferior marca o Q1 (48.75), a linha superior marca Q3 (59.25). O IQR é 10.5 (Q3-Q1). As linhas (whiskers) indicam um desvio de 1.5 IQR a partir do Q1 e Q3. Os pontos fora desse intervalo são geralmente chamados de outliers.
Fazer um boxplot no ggplot() é similar a fazer um histograma
ggplot(dados.scores, aes(x="", y=presente))+ #y = valores da coluna presente
geom_boxplot()ggplot(dados.scores, aes(x="", y=presente))+ #y = valores da coluna presente
geom_boxplot(alpha=0.5, outlier.size = 3)+ #alpha = transparência, outlier.size = tamanho #das bolinhas indicando outlier
labs(y="Notas na prova (presente)")+ #legenda eixo y
theme_bw() #tema do gráfico (fundo branco)Geralmente, quando fazemos boxplots, nós queremos comparar dois grupos. O que está plotado no eixo x? E no eixo y?
No gráfico que vimos, temos um eixo y com os valores das notas, e no eixo x a informação sobre o ano das datas. Podemos fazer isso a partir da nossa tabela dados.scores?
Na verdade, precisamos de uma coluna com as informações das notas e uma dizendo a que ano pertence aquela nota.
Esses formatos se chamam “formato wide” (wide format) e “formato longo” (long format).
Frequentemente precisamos alterar o formato dos nossos dados para fazer análise no R ou em outros programas. A vantagem do R é que essa alteração pode ser feita facilmente com o dplyr a partir da função gather(), e você não precisa fazer isso manualmente.
Lembre-se: NUNCA crie várias planilhas com seus dados se você pode ter apenas uma!
Vamos criar um conjunto em formato longo chamado long.dados. Aplicamos a função gather()informando o nome das duas novas colunas que vamos criar (ano e nota) seguidas pelas colunas que queremos mesclar (presente e passado).
long.dados = dados.scores%>%
gather(ano, nota, presente, passado)Aqui queremos mesclar apenas duas colunas, mas se vc tivesse três, quatro, cinco colunas, deveria apenas seguir listando o nome de todas elas, separando-as com vírgulas.
Clique de novo no conjunto de dados e vc verá que ele foi alterado para um formato longo.
Agora fica fácil criar um boxplot com os comandos que você já conhece.
ggplot(long.dados, aes(x=ano, y=nota))+
geom_boxplot()Vamos deixar o boxplot mais bonito
ggplot(long.dados, aes(x=ano, y=nota))+
geom_boxplot(alpha=0.7, outlier.size = 2)+
labs(x="Ano", y="Notas na prova")+
theme_bw()O formato longo é útil para tirar as medidas de dispersão e tendência central de forma mais rápida. Fazemos isso usando group_by() e summarise()
long.dados%>%
group_by(ano)%>%
summarise(mediana = median(nota), media = mean(nota), dist.interquartil = IQR(nota), desvio.padrao = sd(nota))## # A tibble: 2 x 5
## ano mediana media dist.interquartil desvio.padrao
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 passado 56.5 54.2 10.2 13.1
## 2 presente 55 52.6 10.5 13.4
Lembre-se de que você vai especificando os comandos do dplyr de modo que a função explícita na linha L vai ser o input do que ocorre na linha L+1.
É por isso que primeiro pedimos para agrupar os dados por ano por meio de group_by(), e depois pedimos para que o R nos retorne as medidas solicitadas em summarise()
Hoje você aprendeu a usar o comando filter() para manipular seu conjunto de dados. Vale mencionar como se deve usar esse comando para selecionar dados de uma variável categórica.
filter(ano == "presente") #seleciona apenas as linhas da coluna "ano" preenchidas com "maria". note que o sinal de igual é duplo!!
filter(ano != "presente") #seleciona todas as linhas da coluna "ano" que NÃO estejam preenchidas com "presente".Perceba que a observação que você quer selecionar ou descartar (presente, no caso) deve ser sempre usada entre aspas nesse comando se sua variável é categórica.
Algumas funções para descrever seu conjunto de dados
sd() #calcula o desvio-padrão de um vetor
IQR() #calcula o interquartile range de um vetor (lembre-se: é IQR, não iqr)
summary() #retorna informações sobre 1o e 3o quartil, mediana, média, valor máximo e mínimo de um vetorAlgumas funções para usar o dplyr(parte do pacote tideverse). Lembre-se de que as funções usarão como input o conjunto de dados da linha superior terminada com pipe (%>%).
select() #seleciona uma coluna em um conjunto de dados
filter(x > y) #filtra as linhas da coluna x com valor maior que y
filter(x < y) #filtra as linhas da coluna x com valor menor que y
filter(x == y) #filtra as linhas da coluna x com valor igual a y
filter(x != y) #filtra as linhas da coluna x com valor maior que ySe o valor filtrado for categórico, deve vir entre aspas
Algumas funções para usar o dplyr(parte do pacote tideverse). Lembre-se de que as funções usarão como input o conjunto de dados da linha superior terminada com pipe (%>%).
group_by(x) #agrupa os dados do conjunto especificado na linha anterior pelos valores da coluna x
summarise(mediana = median(y), media = mean(y), dist.interquartil = IQR(y), desvio.padrao = sd(y)) #lista as medidas descritivas que vc especifica para um vetor numérico y; muito útil para ser usado em conjunto com a função group_by Algumas funções para usar o dplyr(parte do pacote tideverse). Lembre-se de que as funções usarão como input o conjunto de dados da linha superior terminada com pipe (%>%).
gather(A, B, x, y, z) #transforma dados em formato wide para formato longo. Aqui, pede-se para formar as novas colunas de nome A e B mesclando os valores presentes nas colunas x, y e zFazer um boxplot é muito parecido com fazer um histograma
ggplot(dados, aes(x, y))+
geom_boxplot() # indica que o gráfico desenhado deve ser um boxplot